﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Security.Cryptography;
using System.Text;

namespace Wicresoft.Shell.Core
{
    public static class RijndaelCryptor
    {
        #region Fields

        private const String mC_RandomKey = "~4`-*(#65!@|/%=^70&2$_+9:;)8[31}";
        private static RijndaelManaged mS_Rijndael;
        private static Encoding mS_TextEncoding;

        #endregion

        #region Constructor

        static RijndaelCryptor()
        {
            mS_Rijndael = new RijndaelManaged();
            mS_Rijndael.KeySize = 256;
            mS_Rijndael.BlockSize = 256;
            mS_Rijndael.Key = GetKeyBytes(mS_Rijndael.KeySize);
            mS_Rijndael.IV = GetKeyBytes(mS_Rijndael.BlockSize);

            mS_TextEncoding = Encoding.UTF8;
        }

        #endregion

        #region Methods

        private static Byte[] GetKeyBytes(Int32 keySize)
        {
            System.Security.Principal.WindowsIdentity curUserId = System.Security.Principal.WindowsIdentity.GetCurrent();
            String curUserSid = curUserId.User.Value;
            Int32 keyLenght = keySize / 8; // The value of KeySize is in bit. (8bit = 1byte)
            String keyStr = String.Empty;

            if (curUserSid.Length > keyLenght)
                keyStr = curUserSid.Substring(0, keyLenght);
            else
                keyStr = String.Concat(curUserSid, mC_RandomKey.Substring(0, keyLenght - curUserSid.Length));

            return Encoding.ASCII.GetBytes(keyStr);
        }

        public static Boolean EncryptorString(String inStr, out Byte[] outByte)
        {
            Boolean state = true;
            Byte[] inByte = null;
            ICryptoTransform cTrans = null;

            outByte = null;
            try
            {
                cTrans = mS_Rijndael.CreateEncryptor();
                inByte = mS_TextEncoding.GetBytes(inStr);
                outByte = cTrans.TransformFinalBlock(inByte, 0, inByte.Length);
            }
            catch
            {
                state = false;
            }
            finally
            {
                if (null != cTrans)
                    cTrans.Dispose();
            }


            return state;
        }

        public static Boolean DecryptorString(Byte[] inByte, out String outStr)
        {
            Boolean state = true;
            Byte[] outByte = null;
            ICryptoTransform cTrans = null;

            outStr = null;
            try
            {
                cTrans = mS_Rijndael.CreateDecryptor();
                outByte = cTrans.TransformFinalBlock(inByte, 0, inByte.Length);
                outStr = mS_TextEncoding.GetString(outByte, 0, outByte.Length);
            }
            catch
            {
                state = false;
            }
            finally
            {
                if (null != cTrans)
                    cTrans.Dispose();
            }

            return state;
        }

        #endregion
    }
}
